package com.cnunicom.modules.tra.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cnunicom.common.utils.PageUtils;
import com.cnunicom.common.utils.Query;
import com.cnunicom.modules.tra.dao.RecordDao;
import com.cnunicom.modules.tra.dto.ExportDTO;
import com.cnunicom.modules.tra.dto.ExportReqDTO;
import com.cnunicom.modules.tra.entity.RecordEntity;
import com.cnunicom.modules.tra.service.*;
import com.cnunicom.modules.tra.vo.HisMebUnitVO;
import com.cnunicom.modules.tra.vo.RewardVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.TemporalAmount;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service("recordService")
public class RecordServiceImpl extends ServiceImpl<RecordDao, RecordEntity> implements RecordService {

    @Autowired
    private HistoryService historyService;

    @Resource
    private HashOperations<String, String, String> hashOperations;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String startDate = (String)params.get("startDate");
        String endDate = (String)params.get("endDate");

        QueryWrapper<RecordEntity> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            wrapper.between("date", startDate, endDate);
        }
        IPage<RecordEntity> page = this.page(new Query<RecordEntity>()
                .getPage(params,"date",false),wrapper);
        return new PageUtils(page);
    }

    /**
     * 定时任务调用方法
     * 凌晨2点查前一天的住房信息,插入记录表
     */
    @Override
    public void tableInsert() {
        final HisMebUnitVO vo = new HisMebUnitVO();
        String date = LocalDate.now().plusDays(-1).toString();
        vo.setRecordDate(date);
        Boolean isHoliday = isHoliday();
        final List<HisMebUnitVO> vos = historyService.queryHisMemUnit(vo);
        final List<RecordEntity> recordEntity = new ArrayList<>(vos.size());

        vos.forEach(HisMebUnitVO -> {
            final RecordEntity entity = new RecordEntity();
            entity.setRoomTypeId(HisMebUnitVO.getRoomtypeId());
            entity.setRoomTypeName(HisMebUnitVO.getFloorRoomName());
            entity.setMebId(HisMebUnitVO.getMebId());
            entity.setMebName(HisMebUnitVO.getMebName());
            entity.setSuperiorId(HisMebUnitVO.getSuperiorId());
            entity.setSuperiorName(HisMebUnitVO.getSuperiorName());
            if (isHoliday) {
                entity.setPrice(HisMebUnitVO.getDisPrice());
            } else {
                entity.setPrice(HisMebUnitVO.getPrice());
            }
            entity.setSuperiorType(HisMebUnitVO.getSuperiorType());
            entity.setIsDel(0);
            entity.setDate(date);
            recordEntity.add(entity);
        });
        this.saveBatch(recordEntity);
    }

    /**
     * 日期判断，如果是周六日或者五一七天和十一七天，返回true
     * @return
     */
    private Boolean isHoliday () {
        LocalDate date = LocalDate.now().plusDays(-1);
        LocalDate firstDay = date.with(TemporalAdjusters.firstDayOfMonth());

        LocalDate startDay = firstDay.plusDays(-1);
        LocalDate endDay = firstDay.plusDays(7);

        if ((date.getMonth() == Month.MAY || date.getMonth() == Month.OCTOBER) &&
                date.isAfter(startDay) && date.isBefore(endDay)) {
            return Boolean.TRUE;
        }

        if (date.getDayOfWeek() == DayOfWeek.SUNDAY || date.getDayOfWeek() == DayOfWeek.SATURDAY) {
            return Boolean.TRUE;
        }

        return Boolean.FALSE;
    }

    @Override
    public Map<String, List<ExportDTO>> excelExport(ExportReqDTO exportReqDTO) {

        //  设置奖励金
        setUpReward(exportReqDTO);
        //  单位
        List<ExportDTO> unit = this.baseMapper.getExportUnit(exportReqDTO);
        //  职员
        List<ExportDTO> staff = this.baseMapper.getExportStaff(exportReqDTO);
        //  总服务台
        List<ExportDTO> front = this.baseMapper.getExportFront(exportReqDTO);
        //  餐厅
        List<ExportDTO> res = this.baseMapper.getExportRes(exportReqDTO);

        HashMap<String, List<ExportDTO>> map = new HashMap<>();
        map.put("unit", unit);
        map.put("staff", staff);
        map.put("front", front);
        map.put("res", res);

        return map;
    }

    /*@Override
    public List<RecordEntity> excelExport(Map<String, Object> params) {

        String startDate = (String)params.get("startDate");
        String endDate = (String)params.get("endDate");

        QueryWrapper<RecordEntity> wrapper = new QueryWrapper<>();
        wrapper.select("room_type_name", "meb_name", "superior_name", "price", "date"
                , "case when superior_type = 0 then '其他单位' else '本单位职员' end as string_type");
        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            wrapper.between("date", startDate, endDate);
        }

        wrapper.orderByAsc("superior_type").orderByAsc("superior_name").orderByAsc("date");
        List<RecordEntity> entities = this.baseMapper.selectList(wrapper);

        // 总金额，奖励金处理
        return rewardHandler(priceHandler(entities));
    }*/

    /**
     * 奖励金设置
     * @param reward
     */
    private void setUpReward(ExportReqDTO reward) {
        // 存到redis里边，不想重新建表了
        hashOperations.put("reward", "unit", reward.getUnitRwd());
        hashOperations.put("reward", "staff", reward.getStaffRwd());
        hashOperations.put("reward", "frontDesk", reward.getFrontDeskRwd());
        hashOperations.put("reward", "res", reward.getResRwd());
    }

    @Override
    public RewardVO rewardInfo() {

        RewardVO vo = new RewardVO();

        String unit = hashOperations.get("reward", "unit");
        String staff = hashOperations.get("reward", "staff");
        String frontDesk = hashOperations.get("reward", "frontDesk");
        String res = hashOperations.get("reward", "res");

        vo.setUnitRwd(unit);
        vo.setStaffRwd(staff);
        vo.setFrontDeskRwd(frontDesk);
        vo.setResRwd(res);

        return vo;
    }

    /**
     * 总金额处理
     * @param entities
     * @return
     */
    /*private List<RecordEntity> priceHandler(List<RecordEntity> entities) {

        Map<String, List<RecordEntity>> maps = entities.parallelStream()
                .collect(Collectors.groupingBy(RecordEntity::getSuperiorName));

        // 各单位以及职员总价
        HashMap<String, BigDecimal> map = new HashMap<>();
        maps.keySet().forEach(key -> {
            BigDecimal decimal = maps.get(key).stream().map(RecordEntity::getPrice).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
            map.put(key, decimal);
        });

        // 扔到原list里边去
        entities.forEach(entity -> {
            map.keySet().forEach(key -> {
                if (entity.getSuperiorName().equals(key)) {
                    entity.setTotalPrice(map.get(key));
                }
            });
        });

        return entities;
    }
*/
    /**
     * 奖励处理
     * @param list
     * @return
     */
    /*private List<RecordEntity> rewardHandler(List<RecordEntity> list) {

        String unit = hashOperations.get("reward", "unit");
        BigDecimal unitRwd = StringUtils.isNotBlank(unit) ? BigDecimal.valueOf(Long.parseLong(unit)) : BigDecimal.ZERO;

        String staff = hashOperations.get("reward", "staff");
        BigDecimal staffRwd = StringUtils.isNotBlank(staff) ? BigDecimal.valueOf(Long.parseLong(staff)) : BigDecimal.ZERO;

        // 按照单位及人员进行分组
        Map<String, Long> maps = list.stream().collect(Collectors
                .groupingBy(RecordEntity::getSuperiorName, Collectors.counting()));

        // 循环设置奖励金
        list.forEach(record -> {
            maps.keySet().forEach(key -> {
                if (record.getSuperiorName().equals(key) && "其他单位".equals(record.getStringType())) {
                       record.setReward(unitRwd);
                       record.setTotalRwd(BigDecimal.valueOf(Math.multiplyExact(maps.get(key),unitRwd.longValue())));
                }
                if (record.getSuperiorName().equals(key) && "本单位职员".equals(record.getStringType())) {
                    record.setReward(staffRwd);
                    record.setTotalRwd(BigDecimal.valueOf(Math.multiplyExact(maps.get(key),staffRwd.longValue())));
                }
            });
        });

        return list;
    }
*/


}

